#include "gui_text.h"
#include "gui_color.h"
#include <assert.h>
#include <stdio.h>

dotfont_library_t __gui_dotfont;
dotfont_t *stdfont=NULL;

static void gui_char_to_surface(dotfont_t *font, char ch, gui_surface_t *surface, int x, int y, uint32_t color)
{
    // check range
    if (x >= surface->w || y >= surface->h)
        return;

    uint8_t *addr = (uint8_t *)dotfont_get_addr(font, ch);
    assert(addr);

    // dprintf("ch %x addr %x\n",ch,addr);

    int i, j;
    uint8_t data;
    for (i = 0; i < 16; i++)
    {
        data = addr[i];
        // dprintf("%x ",data);
        for (j = 7; j >= 0; j--)
        {
            if ((data & (1 << j)))
            {
                gui_surface_putpixel(surface, x + 7 - j, y + i, color);
            }
        }
    }
}

int gui_text_to_surface(char *text, uint32_t color, char *family, gui_surface_t *surface, int x, int y)
{
    stdfont = dotfont_find(&__gui_dotfont, family);
    if (!stdfont)
        return -1;

    char *p = text;
    int _x = x, _y = y;

    while (*p)
    {
        switch (*p)
        {
        case '\n':
            x = 0;
            y += dotfont_get_char_height(stdfont);
            if (y + dotfont_get_char_height(stdfont) <= surface->h)
            {   
                _x = x;
                _y = y;
            }
            break;
        case '\b':
        case '\t':
            break;
        default:
            gui_char_to_surface(stdfont, *p, surface, _x, _y, color);
            _x += dotfont_get_char_width(stdfont);
            if (_x + dotfont_get_char_width(stdfont) > surface->w)
            {
                _x = 0;
                _y += dotfont_get_char_height(stdfont);
                if (_y + dotfont_get_char_height(stdfont) > surface->h)
                    return;
            }
            break;
        }
        p++;
    }
    return 0;
}

// extension show,show all text char to assign char
int gui_text_to_surface_ex(char *text, char ch, uint32_t color, char *family, gui_surface_t *surface, int x, int y)
{
    dotfont_t *stdfont = dotfont_find(&__gui_dotfont, family);
    if (!stdfont)
        return -1;

    char *p = text;
    int _x = x, _y = y;
    while (*p)
    {
        switch (*p)
        {
        case '\n':
        case '\b':
        case '\t':
            break;
        default:
            gui_text_to_surface(stdfont, ch, surface, _x, _y, color);
            _x += dotfont_get_char_width(stdfont);
            break;
        }
        p++;
    }
    return 0;
}
int gui_text_init()
{
    dotfont_init(&__gui_dotfont);
}

uint8_t gui_text_char_width()
{
    return dotfont_get_char_width(stdfont);
}

uint8_t gui_text_char_height()
{
    return dotfont_get_char_height(stdfont);
}